/*
* 表头分组 合并单元格样式
*
* ag-grid 默认 表头分组 时 单元格 未合并
* */
import { onUnmounted, ComputedRef, watch, Ref, ComponentPublicInstance, nextTick } from 'vue'
import { BodyScrollEndEvent } from 'ag-grid-community'
import { treeForEach } from '@/utils/treeHandle'
import { OwnEvents } from '../utils/own-events'

export default function headerGroupStyle(
  ownEvents: OwnEvents,
  attrs: ComputedRef<Record<string, any>>,
  agGridRef: Ref<ComponentPublicInstance>
): void {
  let columnLevelMap = new WeakMap()
  let columnLeafList: any[] = []
  let maxLevel = 0
  const recordLevel = () => {
    const level_set = new Set()
    try {
      treeForEach(attrs.value.columnDefs || [], (column, parent: any) => {
        const parentLevel = columnLevelMap.get(parent) || 0
        const level = parentLevel + 1

        columnLevelMap.set(column, level)

        if (!Array.isArray(column.children) || column.children.length === 0) {
          columnLeafList.push(column)
        }
        level_set.add(level)
      })
    } catch (err:any) {
      console.log(err)
    }

    if (level_set.size <= 1) {
      maxLevel = 1
    } else {
      maxLevel = ([...level_set].reduce((num1:any, num2:any) => (num1 > num2 ? num1 : num2))) as number
    }
  }

  const setStyle = () => {
    const headerRow_normal: HTMLElement[] = Array.from(agGridRef.value.$el.querySelectorAll('.ag-header-container .ag-header-row'))
    const headerRow_pinnedLeft: HTMLElement[] = Array.from(agGridRef.value.$el.querySelectorAll('.ag-pinned-left-header .ag-header-row'))
    let headerRow:any = []
    headerRow_pinnedLeft.forEach((val:any) => {
      if (!val.innerHTML) {
        headerRow = [...headerRow_normal]
      } else {
        headerRow = [...headerRow_normal, ...headerRow_pinnedLeft]
      }
    })
    const exhibit = agGridRef.value.$el.querySelectorAll('.ag-pinned-left-header')
    exhibit.forEach((item:any) => {
      item.style.overflow = 'visible'
    })

    const rowHeightList = headerRow.map((row: { offsetHeight: any }) => row.offsetHeight)

    const leafRow: any[] = []
    headerRow.forEach((item:any, index:number) => {
      if (!((index + 1) % headerRow_normal.length)) {
        leafRow.push(item)
      }
    })
    const leafRowHeight = rowHeightList[rowHeightList.length - 1]
    leafRow.forEach((item:any) => {
      item.style.overflow = 'inherit'
    })

    columnLeafList.forEach((column: any) => {
      const level = columnLevelMap.get(column)

      if (maxLevel !== level) {
        leafRow.forEach((value:any) => {
          const leafNode: HTMLElement | null = value.querySelector(`.ag-header-cell[col-id="${column.field}"]`)
          if (leafNode) {
            const prevRowHeight = []
            const diff = maxLevel - level

            let index = 1
            while (index <= diff) {
              prevRowHeight.push(rowHeightList[maxLevel - 1 - index])

              index++
            }
            const top = prevRowHeight.reduce((sum, item) => sum + item, 0)
            const height = top + leafRowHeight
            const diffHeight = level === 1 ? 1 : 0 // 消除最大跨度cell的border-top重叠问题

            leafNode.style.top = `${-top - diffHeight}px`
            leafNode.style.height = `${height + diffHeight}px`
          }
        })
      }
    })
  }

  const resetParams = () => {
    columnLevelMap = new WeakMap()
    columnLeafList = []
  }

  const init = () => {
    resetParams()
    recordLevel()

    if (maxLevel > 1) {
      setStyle()
    } else {
      resetParams()
    }
  }

  onUnmounted(() => {
    resetParams()
  })

  watch(() => attrs.value.columnDefs, () => {
    nextTick(init)
  }, {
    deep: true
  })

  ownEvents.onGridReady = () => {
    init()
  }

  ownEvents.onBodyScrollEnd = (event: BodyScrollEndEvent) => {
    if (event.direction === 'horizontal') {
      init()
    }
  }
}